home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 October
/
EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso
/
Aminet
/
dev
/
gui
/
textfield.lha
/
Textfield
/
SafeGIRPort
/
SafeGIRPort.a
< prev
next >
Wrap
Text File
|
1995-01-31
|
4KB
|
199 lines
; SafeGIRPort
; Patches ObtainGIRPort() to fix MagicMenu
; and CycleToMenu problem
;
; Based heavily on NewObtainGIRPort, but with
; fixes. Specifically, the caches weren't
; being cleared on removal. Plus, some speed
; improvements in the patch code. Hopefully
; it narrows the gap for someone locking the
; layer between the patch's unlock and original
; call.
INCLUDE 'intuition/cghooks.i'
ObtainGIRPort EQU -$22E
DisplayBeep EQU -$60
OpenLibrary EQU -$228
CloseLibrary EQU -$19E
SetFunction EQU -$1A4
Forbid EQU -$84
Permit EQU -$8A
Wait EQU -$13E
CacheClearU EQU -$27c
Delay EQU -$C6
PutStr EQU -$3B4
AttemptLockLayerRom EQU -$28E
UnlockLayerRom EQU -$1B6
SIGBREAKF_CTRL_C EQU 1<<12
section text,code
_PatchOGR:
moveq #20,d7
; Open libraries
lea gfxname(pc),a1
moveq #36,d0
move.l 4.w,a6
jsr OpenLibrary(a6)
lea GfxBase(pc),a0
move.l d0,(a0)
beq fail1
lea dosname(pc),a1
moveq #36,d0
jsr OpenLibrary(a6)
move.l d0,d2 ; d2 gets DosBase
beq fail2
lea intuiname(pc),a1
moveq #36,d0
jsr OpenLibrary(a6)
move.l d0,d3 ; d3 gets IntuitionBase
beq fail3
jsr Forbid(a6)
; Install patch
move.l d0,a1
lea newObtainGIRPort(pc),a0
move.l a0,d0
move.l #ObtainGIRPort,a0
jsr SetFunction(a6)
lea oldObtainGIRPort(pc),a0
move.l d0,(a0)
; Clear CPU caches to flush data/instruction cache incoherence
jsr CacheClearU(a6)
loop:
jsr Permit(a6)
; Wait for ctrl-C
move.l #SIGBREAKF_CTRL_C,d0
jsr Wait(a6)
jsr Forbid(a6)
; Attempt to remove the patch
move.l d3,a1 ; a1 gets IntuitionBase
move.l oldObtainGIRPort(pc),d0
move.l #ObtainGIRPort,a0
jsr SetFunction(a6)
lea newObtainGIRPort(pc),a0
cmp.l a0,d0
beq.s ok
; Oops, someone has patched over, put it back
move.l d3,a1 ; a1 gets IntuitionBase
move.l #ObtainGIRPort,a0
jsr SetFunction(a6)
; We can't quit, so notify user with a beep
exg d3,a6 ; a6 gets IntutionBase
move.l #0,a0
jsr DisplayBeep(a6) ; it's safe to call display beep inside Forbid()
exg d3,a6 ; a6 gets ExecBase
bra.s loop
ok:
; Clear CPU caches to flush data/instruction cache incoherence
jsr CacheClearU(a6)
jsr Permit(a6)
exg d2,a6 ; a6 gets DosBase
; Notify user of subsequent quit
lea exitmsg(pc),a0
move.l a0,d1
jsr PutStr(a6)
; Wait a second to let other tasks exit from the patch code
; We can't be absolutely sure but this should be enough of a safeguard
moveq #50,d1
jsr Delay(a6)
exg d2,a6 ; a6 gets ExecBase
moveq #0,d7
; Close libraries and exit
move.l d3,a1 ; a1 gets IntutionBase
jsr CloseLibrary(a6)
fail3:
move.l d2,a1 ; a1 gets DosBase
jsr CloseLibrary(a6)
fail2:
move.l GfxBase(pc),a1
jsr CloseLibrary(a6)
fail1:
move.l d7,d0
rts
newObtainGIRPort:
; First we should check for valid input
move.l a0,d0 ; effective compare
; We'll call ObtainGIPort anyway, even if the GadgetInfo is NULL..
beq.s null2
; save some regs
movem.l a0/a5/a6,-(sp)
; assume layer is valid (usually is)
; try to lock it
move.l GfxBase(pc),a6
move.l ggi_Layer(a0),a5 ; only one access of layer ptr
move.l a5,d0 ; effective compare, faster than cmpi
beq.s null1 ; We'll do old stuff if layer is NULL
jsr AttemptLockLayerRom(a6)
ext.l d0 ; effective compare, sets return value
beq.s null3
; Got a lock, free it (layer already in a5, gfxbase in a6)
jsr UnlockLayerRom(a6)
null1:
; layer is null
movem.l (sp)+,a0/a5/a6
null2:
; call original function
move.l oldObtainGIRPort(pc),a1
jmp (a1)
null3:
; Attempt to lock the layer failed, return NULL (set above)
movem.l (sp)+,a0/a5/a6
rts
oldObtainGIRPort:
dc.l 0
GfxBase:
dc.l 0
dosname:
dc.b "dos.library",0
intuiname:
dc.b "intuition.library",0
gfxname:
dc.b "graphics.library",0
exitmsg:
dc.b "SafeGIRPort gone",10,0
dc.b "$VER: SafeGIRPort 1.0 (30.1.95)",0
END